package arg

import (
	"db2s/cM"
	"db2s/global"
	"db2s/linces"
	"encoding/json"
	"fmt"
	"os"
	"runtime"
	"strings"
	"time"
)

func getConfigName(config string) (res string) {
	res = config
	if !strings.Contains(config, "/") {
		sysType := runtime.GOOS
		if strings.EqualFold(sysType, "linux") {
			res = fmt.Sprintf("./%s", config)
		} else if strings.EqualFold(sysType, "windows") {
			res = fmt.Sprintf(".\\%s", config)
		}
	}
	return
}
func ArgInit(argInput ArgInput) (s SecondaryLevel, err error) {
	fmt.Println(fmt.Sprintf("-- [%v] %v report: load configuration file -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if len(argInput.Config) == 0 {
		return
	}
	if s, err = getConfig1(argInput.Config); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return SecondaryLevel{}, err
	}
	return
}

// UnmarshalJSON 处理json: cannot unmarshal string into Go struct field HotSqlOutPut.output.out_time of type inputArg.CustomDuration
func (cd *CustomDuration) UnmarshalJSON(data []byte) error {
	var durationStr string
	if err := json.Unmarshal(data, &durationStr); err != nil {
		return err
	}

	duration, err := time.ParseDuration(durationStr)
	if err != nil {
		return err
	}
	*cd = CustomDuration(duration)
	return nil
}

var driveTo = func(s string) (s1 string) {
	switch strings.ToLower(s) {
	case "oracle":
		return "godror"
	case "mysql":
		return "mysql"
	case "cluster":
		return "mysql"
	case "sqlserver":
		return "mssql"
	case "dm":
		return "dm"
	}
	return
}

func generalModeConfig(Arg InitConfigCmdS) {
	var (
		configPoint *os.File
		err         error
		fileName    string
		keyName     string
	)
	if len(Arg.Object) == 0 {
		return
	}
	switch strings.ToLower(strings.TrimSpace(Arg.Object)) {
	case "task":
		fileName = "gc-task.cnf"
		keyName = "task"
	case "sync":
		fileName = "gc-sync.cnf"
		keyName = "sync"
	case "object":
		fileName = "gc-object.cnf"
		keyName = "object"
	case "struct":
		fileName = "gc-struct.cnf"
		keyName = "struct"
	default:
		return
	}
	if configPoint, err = os.OpenFile(fileName, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644); err != nil {
		global.OsExist()
	}
	tableObjectFile := map[string]*os.File{keyName: configPoint}
	fmt.Println(fmt.Sprintf("-- %v report: start init of %v configure file .", ToolName, keyName))
	if err = cM.InitConfigFile(tableObjectFile, keyName); err != nil {
		fmt.Println("--init fail", err)
		global.OsExist()
	}
	fmt.Println(fmt.Sprintf("-- %v report: init of %v configure file successful.", ToolName, keyName))
	global.OsExist()
}
func InitCmdConfigServer(Config InitConfigCmdS) {
	generalModeConfig(Config)
}
func InitCmdService(initCmd InitCmdS) {
	switch initCmd.Mode {
	case "config":
		InitCmdConfigServer(initCmd.Config)
	}
}
func AuthCmdKeyService(key AuthKeyCmdS) {
	fmt.Println(fmt.Sprintf("-- [%v] %v report: check linces auth -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if !linces.LinesRegister(key.Free, key.Code) {
		//os.Exit(1)
	}
}
func AuthCmdService(authCmd AuthCmdS) {
	switch authCmd.Mode {
	case "key":
		AuthCmdKeyService(authCmd.Key)
	}
}
func RowsDataCmdSyncService(sync rowsDataSyncCmdS) (s SecondaryLevel, err error) {
	if len(sync.Config) == 0 {
		sync.Config = fmt.Sprintf("result/config/%v/sync/gc-sync.cnf", sync.Name)
	}
	if s, err = getConfig1(getConfigName(sync.Config)); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return
	}
	return
}
func RowsDataCmdCheckService(check rowsDataCheckCmdS) (s SecondaryLevel, err error) {
	if len(check.Config) == 0 {
		check.Config = fmt.Sprintf("result/config/%v/sync/gc-rows.cnf", check.Name)
	}
	if s, err = getConfig1(getConfigName(check.Config)); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return
	}
	return
}
func RowsDataCmdService(rowsDataCmd RowsDataCmdS) (s SecondaryLevel, err error) {
	switch rowsDataCmd.Mode {
	case "sync":
		if rowsDataCmd.Sync.Recovered {
			rowsDataCmd.Sync.Recover.Mode = rowsDataCmd.Mode
			rowsDataCmd.Sync.Recover.ParameterValue("result/parameterRecord")
			global.OsExist()
		}
		s, err = RowsDataCmdSyncService(rowsDataCmd.Sync)
	case "check":
		s, err = RowsDataCmdCheckService(rowsDataCmd.Check)
	}
	return
}
func MetaDataCmdObjectService(object MetaDataObjectCmdS) (s SecondaryLevel, err error) {
	if len(object.Config) == 0 {
		object.Config = fmt.Sprintf("result/config/%v/object/gc-object.cnf", object.Name)
	}
	if s, err = getConfig1(getConfigName(object.Config)); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return
	}
	return
}
func MetaDataCmdStructService(Struct MetaDataStructCmdS) (s SecondaryLevel, err error) {
	if len(Struct.Config) == 0 {
		Struct.Config = fmt.Sprintf("result/config/%v/struct/gc-struct.cnf", Struct.Name)
	}
	if s, err = getConfig1(getConfigName(Struct.Config)); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return
	}
	return
}
func MetaDataCmdService(metaDataCmd MetaDataCmdS) (s SecondaryLevel, err error) {
	switch metaDataCmd.Mode {
	case "object":
		s, err = MetaDataCmdObjectService(metaDataCmd.Object)
	case "struct":
		s, err = MetaDataCmdStructService(metaDataCmd.Struct)
	}
	return
}

func TaskScheduleCmdStartService(Start TaskScheduleStartCmdS) (s SecondaryLevel, err error) {
	if len(Start.Config) == 0 {
		return
	}
	if s, err = getConfig1(getConfigName(Start.Config)); err != nil {
		return
	}
	fmt.Println(fmt.Sprintf("-- [%v] %v report: Check parameter validity -- ", time.Now().Format("2006-01-02 15:04:05"), ToolName))
	if err = checkPar(s); err != nil {
		return
	}
	return
}
func TaskScheduleCmdService(taskScheduleCmd TaskScheduleCmdS) (s SecondaryLevel, err error) {
	switch taskScheduleCmd.Mode {
	case "start":
		s, err = TaskScheduleCmdStartService(taskScheduleCmd.Start)
	}
	return
}
func ConfigInit(logThreadSeq int64) (p ConfigParameter, err error) {
	rc.LogThreadSeq = logThreadSeq
	p.ArgInput = cliHelp()
	switch p.ArgInput.Mode {
	case "init":
		InitCmdService(p.ArgInput.InitCmd)
	case "auth":
		AuthCmdService(p.ArgInput.AuthCmd)
	case "rows data":
		p.SecondaryL, err = RowsDataCmdService(p.ArgInput.RowsDataCmd)
	case "meta data":
		p.SecondaryL, err = MetaDataCmdService(p.ArgInput.MetaDataCmd)
	case "task schedule":
		p.SecondaryL, err = TaskScheduleCmdService(p.ArgInput.TaskScheduleCmd)
	default:

	}
	return
}
